# -*- coding: utf-8 -*-
'''
This module provides support for RDFwSchema instances
'''
from BeautifulSoup import BeautifulSoup, NavigableString, Tag
from rdflib import Namespace, ConjunctiveGraph, BNode, Literal, RDF, RDFS
import schema
import parselib
import simplejson
import urllib2

#http://docs.python.org/lib/node406.html
import logging 
logging.basicConfig(level=logging.DEBUG,
					format='%(asctime)s %(levelname)s %(message)s',
					datefmt='%H:%M:%S')
					#filename='/temp/myapp.log',
					#filemode='w')

RDFW = Namespace('http://rdfw.org')
NS1 = Namespace('http://myplace.org')

class Instance:

	def __init__(self, schema, html, graph=ConjunctiveGraph(), ref=''):
		self.schema = schema
		self.html = html
		self.graph = graph
		self.ref = ref
		self.rdfwLinks = []
			
	def dumpjson(self):
		return simplejson.dumps(dict(links= self.rdfwLinks))	   
		
	def parse(self):
		soup = BeautifulSoup(self.html)
		instances = soup.findAll('a', href=schema.INSTANCEURI)
		logging.debug(' Instance.parse; found %d instances of %s' % (len(instances), schema.INSTANCEURI))
		for inst in instances:
			for cls in self.schema.classes:
				node = inst.findNext('a', attrs={"href":cls.classUri})
				logging.debug( 'Instance.parse; clsUri %s; node %s' % (cls.classUri, node))
				if node:
					node = parselib.findFirstAncestor(node, ['body','ul','li','tr','table'])				
					self.parseInstance(cls, node, len(instances)==1)

		#update links to reflect all
		links = soup.findAll('a', href=True)
		for item in links:
			itm = item['href']
			itm = urllib2.splitquery(itm)[0]
			if itm[:7] != 'http://':
				itm = self.schema.ns[itm]
			if self.schema.ns["/"] in itm \
				and not itm in self.schema.stopUri \
				and itm.find(self.schema.rootUri) == 0:
				self.rdfwLinks.append(itm)
	   
				 
	def parseInstance(self, rdfwclass, context, is_singular):	 
		#parents = [tag.name for tag in context.findParents()]
		#print parents
		
		#while context.name not in [u'html',u'ul',u'table',u'body','li','tr']:
		#	context = context.parent
		
		logging.info('Instance.parseInstance: RDFw for: %s, context = <%s>' % ( rdfwclass.classUri, context.name))
		
		if is_singular:
			thisref = self.ref
			logging.debug('Instance.parseInstance; single instance thisref: %s' % thisref )
		else:
			idtag = context.find('a',href=schema.IDURI)
			if idtag:
				id = idtag.findNext('a',href=True)
				thisref = '%s%s' % (self.ref,id['href'])
			else:
				logging.warning('Instance.parseInstance: ID %s not found in multi-instance page, skipping instance' % schema.IDURI)
				return
		
		if thisref.find('http') <0:
			node = self.schema.ns[thisref]
		else:
			node = Namespace(thisref)

		self.graph.add((node, RDF.type, self.schema.ns[rdfwclass.classUri])) # Types should be defined 
		self.graph.add((node, RDFS.label, Literal(thisref)))

		#1st Test - get data following a Data Property tag 
		for tag in rdfwclass.dataUris:
			#handle embedded XML in description field
			if (tag.find('/description') >= 0) and context.find('a',href=tag):
					logging.debug('Instance.parseInstance: parsing XMLLit tag: %s' % tag ) 
					data = parselib.parseLit(context, tag, self.schema.termUri)
					self.graph.add((node, self.schema.ns[tag], Literal(data,datatype=RDF.XMLLiteral)))
					continue
		   
			logging.debug('Instance.parseInstance: parsing Literal tag: %s' % tag ) 
					
			locs = context.findAll('a',href=tag)
			for loc in locs:
				data = ''
				while True:
					loc = loc.nextSibling
					if loc == None:
						break
					try:						
						if loc['href'] in rdfwclass.dataUris + rdfwclass.objectUris:
							break
						if loc['href'] == self.schema.termUri:
							break
					except:
						pass
					if type(loc)==NavigableString:
						data += str(loc)					  
					else:
						guts = loc.findAll(text=True)
						data += str(guts)
				#print '<<'
				self.graph.add((node, self.schema.ns[tag], Literal(data)))
				#print tag, data
			
				
		# 2nd tests for Object URIS
		#print context.prettify #findAll('a')
		for tag in rdfwclass.objectUris:
			logging.debug('Instance.parseInstance: parsing Object tag: %s' % tag ) 
			data = []
			locs = context.findAll('a',href=tag)
			logging.debug('Instance.parseInstance: tag: %s has %d instances' % (tag, len(locs))) 
			for loc in locs:
				while True:
					loc = loc.findNextSibling('a')
					if loc == None: break
					if loc['href'] in rdfwclass.dataUris + rdfwclass.objectUris: break
					if loc['href']== self.schema.termUri: break
					data.append(loc['href'])
			
			for itm in data:		
				#print 'TEST -->', tag, itm
				if itm[:7] != 'http://':
					itm = self.schema.ns[itm]
				self.graph.add((node, self.schema.ns[tag], itm))
				#if self.schema.ns["/"] in itm:
				#	self.rdfwLinks.append(itm)
				
		#print self.graph.serialize() #destination, format, base, encoding)
			
 